package com.pubinfo.passbook.api.eip.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.pubinfo.passbook.api.eip.UserInfoService;
import com.pubinfo.passbook.common.entity.TRabbitmqOrgConvert;
import com.pubinfo.passbook.common.entity.TRabbitmqPersonConvert;
import com.pubinfo.passbook.common.entity.TSubsidiaryInfo;
import com.pubinfo.passbook.common.entity.TSystemRole;
import com.pubinfo.passbook.common.exception.ServiceException;
import com.pubinfo.passbook.common.mapper.TRabbitmqOrgConvertMapper;
import com.pubinfo.passbook.common.mapper.TRuleRoleMapper;
import com.pubinfo.passbook.common.mapper.TSubsidiaryInfoMapper;
import com.pubinfo.passbook.common.mapper.TSystemRoleMapper;
import com.pubinfo.passbook.common.model.bo.SubsidiaryDepartment;
import com.pubinfo.passbook.common.model.bo.rabbitmq.TbCert;
import com.pubinfo.passbook.common.model.bo.witeoff.CityInfo;
import com.pubinfo.passbook.common.model.dubbo.ESBServiceData;
import com.pubinfo.passbook.common.model.http.eip.UserInfo;
import com.pubinfo.passbook.common.model.http.eip.UserInformation;
import com.pubinfo.passbook.common.service.cache.JedisManage;
import com.pubinfo.passbook.common.service.dubbo.DubboService;
import com.pubinfo.passbook.common.service.master.TRabbitmqPersonConvertService;
import com.pubinfo.passbook.common.service.master.TRabbitmqPersonService;
import com.pubinfo.passbook.common.service.master.TSystemRoleService;
import com.pubinfo.passbook.common.utils.HttpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * EIP登录后用户信息获取
 *
 * @author zhouch
 * @date 2021/12/1 15:47
 */
@Service
public class UserInfoServiceImpl implements UserInfoService {

    @Autowired
    DubboService dubboService;

    @Autowired
    TRabbitmqPersonService personService;

    @Autowired
    TRuleRoleMapper ruleRoleMapper;
    @Resource
    TSystemRoleService roleService;
    @Autowired
    TSystemRoleMapper roleMapper;
    @Autowired
    TSubsidiaryInfoMapper infoMapper;
    @Resource
    JedisManage jedis;
    @Resource
    TRabbitmqOrgConvertMapper convertMapper;
    @Resource
    TRabbitmqPersonConvertService personConvertService;
    final String SUCCESS_RESULT = "OK";

    @Override
    public String userNsrsbhByAcct(String acct) {
        ESBServiceData.CertDetail certDetail = dubboService.getPersonsDetailByIdNo(acct);
        if (certDetail != null) {
            String areaName = certDetail.getSubsidiaryName();
            CityInfo info = infoMapper.findCityInfoByNsrsbh(areaName);
            if (info != null) {
                return info.getNsrsbh();
            }
        }
        return null;
    }

    @Override
    public TSystemRole getCurrentUserRole() {
        List<TSystemRole> roleList = listCurrentUserRole(getCurrentAcct());
        UserInfo userInfo = getCurrentUserInfo();
        //取第一个
        if (!CollectionUtils.isEmpty(roleList)) {
            roleList = roleList.stream().filter(role -> role.getNsrsbh().equals(userInfo.getNsrsbh())).collect(Collectors.toList());
        }
        return roleList.get(0);
    }

    /**
     * 第一次登录时使用UserInfo的jthrLoginName获取角色
     *
     * @return
     */
    @Override
    public TSystemRole getCurrentUserRoleByNoLogin(String jthrLoginName) {
        String acct = jthrLoginName.substring(0, jthrLoginName.indexOf("@"));
        List<TSystemRole> roleList = listCurrentUserRole(acct);
        //取第一个
        return roleList.get(0);
    }

    @Override
    public List<TSystemRole> listCurrentUserRole() {
        return listCurrentUserRole(getCurrentAcct());
    }

    @Override
    public List<TSystemRole> listCurrentUserRole(String currentAcct) {
        List<TSubsidiaryInfo> tSubsidiaryInfos = new LambdaQueryChainWrapper<>(infoMapper).eq(TSubsidiaryInfo::getAuditUser, currentAcct).list();
        /**
         * 先查询用户是否为医药费审核员，如果不是，则查询角色表，关联后返回用户角色信息
         * 如果是，则直接返回医药费审核员相关信息
         */
        List<TSystemRole> roleList = new ArrayList<>();
        if (CollectionUtils.isEmpty(tSubsidiaryInfos)) {
            String nsrsbh = userNsrsbhByAcct(currentAcct);
            roleList = roleMapper.listRoleByAcct(currentAcct);

            //查询账号拥有的部门报账员
            List<TRabbitmqOrgConvert> converts = new LambdaQueryChainWrapper<TRabbitmqOrgConvert>(convertMapper).eq(TRabbitmqOrgConvert::getAuditUser, currentAcct).list();
            if (!CollectionUtils.isEmpty(converts)) {
                //根据部门查询公司组织代码
                List<SubsidiaryDepartment> subsidiaryDepartmentList = infoMapper.listByAcctUser(currentAcct);
                roleList = subsidiaryDepartmentList.stream().map(subsidiaryDepartment -> {
                    TSystemRole role = new TSystemRole(subsidiaryDepartment);
                    return role;
                }).collect(Collectors.toList());
            }
            if (CollectionUtils.isEmpty(roleList)) {
                roleList = new LambdaQueryChainWrapper<TSystemRole>(roleMapper).eq(TSystemRole::getRoleCode, "passbook_user").list();
            }
            roleList.forEach(role -> {
                role.setNsrsbh(nsrsbh);
            });
        } else {
            roleList = TSystemRole.toList(tSubsidiaryInfos);
        }
        roleList.forEach(role -> {
            List<TSystemRole> roles = new LambdaQueryChainWrapper<TSystemRole>(roleMapper).eq(TSystemRole::getRoleCode, role.getRoleCode()).list();
            role.setId(roles.get(0).getId());
        });
        return roleList;
    }

    @Override
    public UserInfo getCurrentUserInfo(String token) {
        String key = USERINFO_CACHE_KEY_PREFIX + token;

        String resultJson = jedis.getStr(key);

        return UserInfo.formStr(resultJson);
    }

    @Override
    public TSystemRole getCurrentUserRole(String nsrsbh) {
        List<TSystemRole> roleList = listCurrentUserRole(getCurrentAcct());
        //取第一个
        if (!CollectionUtils.isEmpty(roleList)) {
            roleList.stream().filter(role -> role.getNsrsbh().equals(nsrsbh));
        }
        return roleList.get(0);
    }

    @Override
    public String getCurrentUserNsrsbh() {
        String acct = getCurrentAcct();
        ESBServiceData.CertDetail certDetail = dubboService.getPersonsDetailByIdNo(acct);
        if (certDetail != null) {
            String areaName = certDetail.getSubsidiaryName();
            CityInfo info = infoMapper.findCityInfoByNsrsbh(areaName);
            if (info != null) {
                return info.getNsrsbh();
            }
        }
        return null;
    }

    @Override
    public UserInfo getCurrentUserInfo() {
        String token = HttpUtils.getToken(getHttpServletRequest());
        return getCurrentUserInfo(token);
    }

    @Override
    public String getCurrentAcctId() {
        String acct = getCurrentAcct();
        TRabbitmqPersonConvert rabbitmqPerson = personConvertService.getPersonByAcct(acct);
        if (rabbitmqPerson != null) {
            return String.valueOf(rabbitmqPerson.getAcctId());
        }
        return null;
    }

    @Override
    public String getCurrentAcct() {
        UserInfo userInfo = getCurrentUserInfo();
        if (userInfo != null) {
            String jthrLoginName = userInfo.getJthrLoginName();
            String acct = jthrLoginName.substring(0, jthrLoginName.indexOf("@"));
            return acct;
        }
        return null;
    }

    @Override
    public TRabbitmqPersonConvert getCurrent4AUserInfo(String token) {

        return personConvertService.getPersonByAcct(getCurrentAcct());
    }

    @Override
    public Boolean judgeRole(String roleCode) {
        UserInfo userInfo = getCurrentUserInfo();
        String jthrLoginName = userInfo.getJthrLoginName();
        String acct = jthrLoginName.substring(0, jthrLoginName.indexOf("@"));
        List<TSystemRole> roles = ruleRoleMapper.findRolesByAcct(acct, roleCode);
        return !CollectionUtils.isEmpty(roles);
    }

    @Override
    public TSystemRole getRoleInfo() {
//        UserInfo userInfo = getCurrentUserInfo();
//        String jthrLoginName = userInfo.getJthrLoginName();
//        String acct = jthrLoginName.substring(0, jthrLoginName.indexOf("@"));
        return getCurrentUserRole();
    }

    @Override
    public Boolean setCurrentUserInfo(String token, UserInfo user) {
        String key = USERINFO_CACHE_KEY_PREFIX + token;

        // 设置用户真实姓名, EIP 可能不存在该字段
        user.setRealname(getPersonCertByAcct(user).getCertName());

        String result = jedis.putStr(key, user.toString());

        return result.contentEquals(SUCCESS_RESULT);

    }

    @Override
    public Boolean setNsrsbhToCurrentUserInfo(String nsrsbh) {
        String key = USERINFO_CACHE_KEY_PREFIX + HttpUtils.getToken(getHttpServletRequest());

        UserInfo info = getCurrentUserInfo();
        info.setNsrsbh(nsrsbh);

        String result = jedis.putStr(key, info.toString());

        return result.contentEquals(SUCCESS_RESULT);
    }

    @Override
    public UserInformation getUserInformation()
    {
        String token = HttpUtils.getToken(getHttpServletRequest());
        return new UserInformation(getCurrentUserInfo(),token,listCurrentUserRole());
    }


    /**
     * 通过userinfo的acct获得用户身份信息
     * (EIP方的真实姓名存在数据错误，所以真实姓名从4A处获取)
     *
     * @param info
     * @return
     */
    public TbCert getPersonCertByAcct(UserInfo info) {
        TRabbitmqPersonConvert person = get4APersonByUserInfo(info);
        try {
            return person.getTbCert().get(0);

        } catch (NullPointerException exp) {
            throw new ServiceException("获取用户身份信息数据失败从tb_cert字段，请检查该数据是否为脏数据. acct = " + person.getAcct());
        }
    }

    public HttpServletRequest getHttpServletRequest() {
        //获取request、response、session
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            return requestAttributes.getRequest();
        }
        return null;
    }

    public TRabbitmqPersonConvert get4APersonByUserInfo(UserInfo info) {
        String acct = info.getJthrLoginName().substring(0, info.getJthrLoginName().indexOf("@"));
        TRabbitmqPersonConvert person = new LambdaQueryChainWrapper<>(personConvertService.getBaseMapper())
                .eq(TRabbitmqPersonConvert::getAcct, acct)
                .one();
        if (person == null) {
            throw new ServiceException("不存在该用户");
        }
        return person;
    }
}
